﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

using System.Diagnostics;
using System.IO;
using System.Text;

using Microsoft.Deployment.WindowsInstaller;

namespace TPG.SharePoint.Workflow.Install.SharePoint
{

    public class SharePointCustomActions
    {
        [CustomAction]
        public static ActionResult DeleteSolution(Session session)
        {
            session.Log("DeleteSolution: " + session.CustomActionData.ToString());
            // retrieve and verify parameters
            string solutionName = session.CustomActionData["solutionName"];

            session.Log("DeleteSolution: Deleting solution named '{0}'.", solutionName);
            
            Dictionary<string, string> parameters =
               new Dictionary<string, string>();
            parameters.Add("o", "deletesolution");
            parameters.Add("name", "\"" + solutionName + "\"");

            try
            {
                ExecuteSTSADM(FindSTSPath(), parameters);
                session.Log("DeleteSolution: Solution named '{0}' deleted successfully.", solutionName);

                return ActionResult.Success;
            }
            catch (Exception e)
            {
                session.Log("DeleteSolution: Exception: " + e.Message);
                return ActionResult.Failure;
            }
        }

        [CustomAction]
        public static ActionResult AddSolution(Session session)
        {
            if (session.GetMode(InstallRunMode.Scheduled))
            {
                string wspPath = session.CustomActionData["wspPath"];                

                session.Log("AddSolution: Adding solution at location '{0}'.", wspPath); 

                string stsPath = FindSTSPath();
                if (String.IsNullOrEmpty(stsPath))
                {
                    session.Log("AddSolution: " + "The SharePoint administration tool STSADM.exe could not be found. Please install the host forms solution package manually.");
                }
                else
                {
                    Dictionary<string, string> parameters =
                        new Dictionary<string, string>();
                    parameters.Add("o", "addsolution");
                    parameters.Add("filename", "\"" + wspPath + "\"");
                    ExecuteSTSADM(stsPath, parameters);

                    //Dictionary<string, string> deployParameters =
                    //    new Dictionary<string, string>();
                    //deployParameters.Add("o", "deploysolution");
                    //deployParameters.Add("name", wspName);
                    //deployParameters.Add("immediate", "");
                    //deployParameters.Add("allowgacdeployment", "");
                    //ExecuteSTSADM(deployParameters);
                }
            }

            return ActionResult.Success;
        }

        [CustomAction]
        public static ActionResult DeploySolution(Session session)
        {
            // retrieve and verify parameters
            string solutionName = session.CustomActionData["solutionName"];

            session.Log("DeploySolution: Deploying solution named '{0}'.", solutionName);

            Dictionary<string, string> parameters =
               new Dictionary<string, string>();
            parameters.Add("o", "deploysolution");
            parameters.Add("name", "\"" + solutionName + "\"");
            parameters.Add("local", "");
            parameters.Add("allowgacdeployment", "");

            try
            {
                ExecuteSTSADM(FindSTSPath(), parameters);
                session.Log("DeploySolution: Solution named '{0}' deployed successfully.", solutionName);

                return ActionResult.Success;
            }
            catch (Exception e)
            {
                session.Log("DeleteSolution: Exception: " + e.Message);
                return ActionResult.Failure;
            }
        }

        static void ExecuteSTSADM(string stsPath, Dictionary<string, string> parameters)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo(
                stsPath, BuildArguments(parameters));
            Process process = Process.Start(startInfo);
            process.WaitForExit();
            
        }

        private static string BuildArguments(Dictionary<string, string> parameters)
        {
            StringBuilder argumentBuilder = new StringBuilder();
            string[] keys = new string[parameters.Count];
            parameters.Keys.CopyTo(keys, 0);
            if (keys.Length > 0)
            {
                AddParameter(argumentBuilder, keys[0], parameters[keys[0]]);
                for (int i = 1; i < keys.Length; i++)
                {
                    argumentBuilder.Append(" ");
                    AddParameter(argumentBuilder, keys[i], parameters[keys[i]]);
                }
            }
            return argumentBuilder.ToString();
        }

        private static void AddParameter(StringBuilder argumentBuilder,
            string key, string value)
        {
            argumentBuilder.Append("-" + key);
            if (String.IsNullOrEmpty(value) == false)
            {
                argumentBuilder.Append(" " + value);
            }
        }

        //public override void Uninstall(System.Collections.IDictionary savedState)
        //{
        //    string wspName = "TPG_SharePoint_Workflow_1_0_0.wsp";
        //    string installDir = Context.Parameters["InstallDir"];
        //    string wspPath = Path.Combine(
        //        installDir, wspName);
        //    FindSTSPath();
        //    if (String.IsNullOrEmpty(_stsadmPath) == false)
        //    {
        //        Dictionary<string, string> deployParameters =
        //            new Dictionary<string, string>();
        //        deployParameters.Add("o", "retractsolution");
        //        deployParameters.Add("name", wspName);
        //        deployParameters.Add("immediate", "");
        //        ExecuteSTSADM(deployParameters);

        //        Dictionary<string, string> parameters =
        //            new Dictionary<string, string>();
        //        parameters.Add("o", "deletesolution");
        //        parameters.Add("name", wspName);
        //        ExecuteSTSADM(parameters);

        //    }

        //    base.Uninstall(savedState);
        //}

        private static string FindSTSPath()
        {
            foreach (DriveInfo drive in DriveInfo.GetDrives())
            {
                string rootpath = drive.RootDirectory.ToString();
                string stsPath =
                    Path.Combine(
                    rootpath, @"Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\bin\STSADM.exe");
                if (File.Exists(stsPath))
                    return stsPath;
            }

            return null;
        }
    }
}
